<template>
  <div class="page_root" :key="queryUpdateFlag" data-page-name="对比组件" data-page-identification="q_1s7u9kp2yy">
    <a-spin :spinning="pageLoading.loading" :tip="pageLoading.tip">
      <!-- begin vid_qrxjy9bzon 自定义模板_etpw669h87 -->
      <div style="display: flex; gap: 20px">
        <div style="flex: 1">
          <h3 class="mg16">原始版本</h3>
          <div v-html="leftDiffHtml" class="diff-box mg16"></div>
        </div>
        <div style="flex: 1">
          <h3 class="mg16">最新版本</h3>
          <div v-html="rightDiffHtml" class="diff-box"></div>
        </div>
      </div>
      <!-- end vid_qrxjy9bzon 自定义模板_etpw669h87 -->
    </a-spin>
  </div>
</template>
<script setup lang="tsx">
  import {
      h, ref, reactive, toRaw, markRaw, watch, computed,
      onBeforeMount, onMounted, onBeforeUnmount, onUnmounted, onActivated, onDeactivated
    } from "vue";
    import { useRoute, useRouter } from 'vue-router';
    const router = useRouter();
    const route = useRoute();
    import { get, post, put, del, request, requestWithHeaders } from '@/utils/http/Axios';
    import { cloneDeep, localGet, merge, getDifferenceArray, traversalTreeStructure, checkCaseCondition, renderStringInTemplate, handleBreadcrumbJump, throttle, permission, getComponentParamsValue } from '@/utils/index';
    import { isNullOrEmpty, isEmptyArr, isNullOrUnDef, isContained, isArray, isEmpty, isObject } from '@/utils/is';
    import dayjs from 'dayjs';
    import { getPagePcChartsDataSourceConvert } from '@/utils/chart';
    import { message, notification, Modal } from 'ant-design-vue'
    import { propertyFormatByNumber, propertyFormatByPercentage, propertyFormatByDate, parseSubFromDataList } from '@/utils/format';
    import colorTheme from '@/design/custom-theme.json';
    
    import UserTableRecords from '@/model/UserTableRecords';
    import { getAppBaseUrl } from '@/utils/index';
    import { sendToken } from "@/hooks/useIframeToken";
    import { useSystemStore } from "@/store/modules/system";
    const systemStore = useSystemStore();
    



      // 获取传入的流程ID和组件参数
      const props = defineProps({
            'processInstanceId': {
            type: [String,Number,Boolean],
            default: undefined,
        },
      'oldData': {
            type: [String],
            default: undefined,
        },
      'newData': {
            type: [String],
            default: undefined,
        },
      })
      const immediateWatch = (source, callback) => {
        watch(source, callback, {deep: true,immediate: true })
      }



  /* -------------------------- 属性定义 -------------------------- */

      const setTimeOutList = [];
      const pageLoading = reactive({
        loading: false,
        tip: undefined
      });
      const authInfo = localGet('app-user-store');




      // 处理校验
      const setSubFormName =(parentInfo, name)=>{
        return [parentInfo.parents, parentInfo.cycleIndex, name];
      }


  /* ========================== 属性定义 ========================== */


  /* -------------------------- 元素数据引用 -------------------------- */


  /* ========================== 元素数据引用 ========================== */


  /* -------------------------- 页面数据 -------------------------- */


  /* ========================== 页面数据 ========================== */



  /* -------------------------- 响应 -------------------------- */

  /* ========================== 响应 ========================== */


  /* -------------------------- 函数 -------------------------- */

  /* ========================== 函数 ========================== */


  /* -------------------------- 页面参数 -------------------------- */

    const pageParameter_state = reactive({
        'processInstanceId': props.processInstanceId ?? route.query.processInstanceId,
    })

  /* ========================== 页面参数 ========================== */


  /* -------------------------- 组件事件处理方法 -------------------------- */

    // ---------------------------- 组件数据同步 ----------------------------

    // ============================ 组件数据同步 ============================


  /* ========================== 组件事件处理方法 ========================== */


  /* -------------------------- 生命周期 -------------------------- */
  // 用于参数变更后重新执行自定义指令
      const queryUpdateFlag = ref(0);
      onMounted(() => { ;

    });

    onUnmounted(() => {
      // 销毁定时器
      setTimeOutList.forEach(({ repeat, timer }) => {
        repeat ?  clearInterval(timer): clearTimeout(timer);
      });
    });

  /* ========================== 生命周期 ========================== */


  /* -------------------------- 数据关联处理 -------------------------- */





  /* -------------------------- 表单数据同步 -------------------------- */
  /* ========================== 表单数据同步 ========================== */

  /* ========================== 数据关联处理 ========================== */


  /* -------------------------- 不同组件自定义的处理逻辑 -------------------------- */

  /* ========================== 不同组件自定义的处理逻辑 ========================== */


  // ================================定制化逻辑========================================
  import { diff_match_patch } from 'diff-match-patch'
      import { watchEffect } from 'vue'
      const { oldData, newData } = props

      const dmp = new diff_match_patch()
      const diffs = ref([])

      const originalText = ref('')

      const updatedText = ref('')

      // 计算 diff 结果
      diffs.value = dmp.diff_main(originalText.value, updatedText.value)
      dmp.diff_cleanupSemantic(diffs.value)

      function getLineDiffs(orig, updated) {
          // 处理 undefined/null，确保 orig 和 updated 至少是空字符串
          orig = orig || ''
          updated = updated || ''

          // 如果传入的是非字符串（如数字），转换为字符串
          if (typeof orig !== 'string') orig = String(orig)
          if (typeof updated !== 'string') updated = String(updated)

          const origLines = orig.split('\n')
          const updatedLines = updated.split('\n')
          const maxLen = Math.max(origLines.length, updatedLines.length)
          const result = [] // 返回 [leftHtml, rightHtml, rowClass]

          for (let i = 0; i < maxLen; i++) {
              const o = origLines[i] ?? ''
              const u = updatedLines[i] ?? ''
              const diffs = dmp.diff_main(o, u)
              dmp.diff_cleanupSemantic(diffs)

              const leftParts = []
              const rightParts = []
              let hasChanges = false // 标记当前行是否有差异

              for (const [type, text] of diffs) {
                  const safe = escapeHtml(text)
                  if (type === 0) {
                      leftParts.push(safe)
                      rightParts.push(safe)
                  } else {
                      hasChanges = true // 检测到差异
                      if (type === -1) {
                          leftParts.push(`<span class="delete">${safe}</span>`)
                      } else if (type === 1) {
                          rightParts.push(`<span class="insert">${safe}</span>`)
                      }
                  }
              }

              // 如果有变化，添加 modified 类名；否则为空字符串
              const rowClass = hasChanges ? 'modified' : ''
              result.push([leftParts.join(''), rightParts.join(''), rowClass])
          }

          return result
      }
      const diffLines = computed(() => getLineDiffs(originalText.value, updatedText.value))
      const leftDiffHtml = computed(() =>
          diffLines.value
              .map(
                  ([left, _, rowClass]) =>
                      `<div class="diff-line${rowClass ? ' ' + rowClass : ''}">${left || '&nbsp;'}</div>`
              )
              .join('')
      )

      const rightDiffHtml = computed(() =>
          diffLines.value
              .map(
                  ([_, right, rowClass]) =>
                      `<div class="diff-line${rowClass ? ' ' + rowClass : ''}">${right || '&nbsp;'}</div>`
              )
              .join('')
      )
      // 防止 XSS
      function escapeHtml(text) {
          return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
      }
      watchEffect(() => {
          if (oldData || newData) {
              originalText.value = oldData
              updatedText.value = newData
              console.log('触发')
          }
      })
</script>
<style lang="less" scoped>
  .page_root {
  width: 100%;
  height: 100%;
  overflow: auto;
  }
  .page_root :deep(.@{ant-prefix}-spin-nested-loading),
  .page_root :deep(.@{ant-prefix}-spin-container)
   {
      height: 100%;
  }
  .page_root :deep(.@{ant-prefix}-spin-container .@{ant-prefix}-table-wrapper)
   {
      display: flex;
      flex-flow: column nowrap;
      justify-content: flex-start;
  }
  .page_root :deep(.@{ant-prefix}-table)
   {
    flex: auto;
    overflow: auto;
  }
  .table-moreBtn_down {
    overflow: hidden; white-space: nowrap; text-overflow: ellipsis; width: 100px;
  }

  .table-moreBtn_menu :deep(.table-moreBtn_menu-item):hover {
    background: #ebf1ff;
  }

  /*  表格树结构样式处理，展开按钮层级增加*/
  :deep(.@{ant-prefix}-table-row-expand-icon) {
    z-index: 1;
  }
  /*  表格树结构 由于每个表格项采用自定义组件，使用绝对定位布局，开启树结构导致显示异常，暂时使用层级定位位置 */
  :deep(.@{ant-prefix}-table-row-level-1 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
    left: 15px !important;
    width: calc(100% - 15px);
  }
  :deep(.@{ant-prefix}-table-row-level-2 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
    left: 30px !important;
    width: calc(100% - 30px);
  }
  :deep(.@{ant-prefix}-table-row-level-3 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
    left: 45px !important;
    width: calc(100% - 45px);
  }
  :deep(.@{ant-prefix}-table-row-level-4 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
    left: 60px !important;
    width: calc(100% - 60px);
  }

  /* 穿梭框改变默认样式，为根据组件样式控制左右栏宽度。 */
  :deep(.@{ant-prefix}-transfer-list)
   {
      height: 100%;
      width: 50%;
  }


   :deep(.diff-box) {
          border: 1px solid #ccc;
          padding: 10px;
          white-space: pre-wrap;
          font-family: monospace;
          background-color: #f9f9f9;
          border-radius: 4px;
          color: #262626;
      }
      :deep(.delete) {
          background-color: #ffd6d6; /* 更深的删除背景 */
          color: #ff2a00;
          text-decoration: line-through;
      }
      :deep(.insert) {
          background-color: #c8facc; /* 更深的插入背景 */
          color: #30bf78;
      }
      :deep(.modified) {
          background: rgba(56, 117, 255, 0.1);
          border-left: 2px solid #3875ff; // 左侧黄色边框
          margin: 2px 0;
          padding: 2px 5px;
      }
      .mg16 {
          //margin-bottom: 16px;
      }
</style>